//
//  ViewController.m
//  GCDSocketClient
//
//  Created by chenf on 2022/5/21.
//

#import "ViewController.h"
#import "GCDAsyncSocket.h"
#import "Masonry.h"

#define Image_Command 0x00000001
#define Video_Command 0x00000002
#define Json_Command 0x00000003
#define Text_Command 0x00000004
#define UNOWKEN_Command 0x00000005
#define Split_Line_Command 0x00000009

#define SocketServerIPAddress @"127.0.0.1"
#define SocketServerPORT 9999

@interface ViewController ()<GCDAsyncSocketDelegate>

@property(nonatomic,strong)GCDAsyncSocket *socket;
@property(nonatomic,strong)UITextField *inputField;
@property(nonatomic,strong)NSMutableData *dataArray;
@property(nonatomic,strong)UIImageView *imageView;
@property(nonatomic,assign)unsigned int totalSize;
@property(nonatomic,assign)unsigned int currentCommandID;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    UIButton *linkBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    linkBtn.backgroundColor = UIColor.systemOrangeColor;
    [linkBtn setTitle:@"Client Socket" forState:UIControlStateNormal];
    linkBtn.titleLabel.font =[UIFont systemFontOfSize:12];
    [self.view addSubview:linkBtn];
    [linkBtn addTarget:self action:@selector(createSocket) forControlEvents:UIControlEventTouchUpInside];
    
    CGFloat width = 88,gap = 10,left = (UIScreen.mainScreen.bounds.size.width-width*3)/4;
    [linkBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_top).offset(44);
        make.left.equalTo(self.view).offset(left);
        make.width.mas_equalTo(@(width));
        make.height.mas_equalTo(@(32));
    }];
    UIButton *reconnectBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    reconnectBtn.backgroundColor = UIColor.blueColor;
    [reconnectBtn setTitle:@"ReCon Socket" forState:UIControlStateNormal];
    [self.view addSubview:reconnectBtn];
    reconnectBtn.titleLabel.font =linkBtn.titleLabel.font;
    [reconnectBtn addTarget:self action:@selector(reConnectSocket) forControlEvents:UIControlEventTouchUpInside];
    
    [reconnectBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(linkBtn);
        make.left.equalTo(linkBtn.mas_right).offset(left);
        make.width.height.equalTo(linkBtn);
    }];
    
    
    UIButton *disConnectBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    disConnectBtn.backgroundColor = UIColor.systemOrangeColor;
    [disConnectBtn setTitle:@"DisCon Socket" forState:UIControlStateNormal];
    disConnectBtn.titleLabel.font =linkBtn.titleLabel.font;
    [self.view addSubview:disConnectBtn];
    [disConnectBtn addTarget:self action:@selector(disConnectSocket) forControlEvents:UIControlEventTouchUpInside];
    
    [disConnectBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(linkBtn);
        make.left.equalTo(reconnectBtn.mas_right).offset(left);
        make.width.height.equalTo(linkBtn);
    }];
    
    
    //输入框内容
    self.inputField = [[UITextField alloc] init];
    self.inputField.layer.borderWidth = 2;
    self.inputField.layer.borderColor = [UIColor grayColor].CGColor;
    [self.view addSubview:self.inputField];
    [_inputField mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(linkBtn.mas_bottom).offset(gap);
        make.left.equalTo(linkBtn);
        make.right.equalTo(reconnectBtn.mas_right);
        make.height.mas_equalTo(@(36));
    }];
    //发送消息框
    UIButton *sendBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    sendBtn.backgroundColor = UIColor.blueColor;
    [sendBtn setTitle:@"Send" forState:UIControlStateNormal];
    sendBtn.titleLabel.font =[UIFont systemFontOfSize:10];
    [self.view addSubview:sendBtn];
    [sendBtn addTarget:self action:@selector(sendMessage) forControlEvents:UIControlEventTouchUpInside];
    
    [sendBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(_inputField);
        make.left.equalTo(self.inputField.mas_right);
        make.width.mas_equalTo(@(44));
        make.height.mas_equalTo(@(36));
    }];
    //展示图片
    self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"testSocket.jpg"]];
    [self.view addSubview:self.imageView ];
    [self.imageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(_inputField.mas_bottom).offset(44);
        make.left.equalTo(linkBtn.mas_left);
        make.right.equalTo(disConnectBtn.mas_right);
//        make.width.mas_equalTo(@(392));
        make.height.mas_equalTo(@(120));
        
    }];
}
#pragma mark -- 创建socket
-(void)reConnectSocket{
    //创建socket
    if(self.socket == nil || !self.socket.isConnected){
        [self createSocket];
    }
}
-(void)disConnectSocket{
    [self.socket disconnect];
    self.socket = nil;
}
-(void)createSocket{
    //创建Socket
    if(_socket == nil){
        _socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
    }
    //链接Socket
    if(!self.socket.isConnected){
        NSError *error;
        [self.socket connectToHost:SocketServerIPAddress onPort:SocketServerPORT withTimeout:-1 error:&error];
        if (error) NSLog(@"%@",error);
    }
}

#pragma mark -- 重连
-(void)sendMessage{
    if(self.inputField.text.length>0){
      [self.socket writeData:[self.inputField.text dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:123456];
    }
    self.inputField.text = @"";
    [self.socket readDataWithTimeout:-1 tag:123456];
}

-(void)sendHeatMsg{
    if(!self.socket.isConnected) return;
    [self.socket readDataWithTimeout:-1 tag:123456];
    
//    NSString *msg = @"heatMsg\n";
//    NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
//    [self.socket writeData:data withTimeout:-1 tag:12345];
}
-(void)sendInitData{
   //第一次链接成功后，发送客户端初始化信息
    NSDictionary *dict =@{@"userId": @"18011111122",@"buss":@"mobileClientInit"};
//    NSString *headerStr = [NSString stringWithFormat:@"{\"userId\":%@,\"buss\":\"mobileClientInit\"}", @"18011538429"];
    NSData *data =[NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
    [_socket writeData:data withTimeout: -1 tag:10000];
}
// 报文格式 4Byte包长+4Byte包头长度+包头+包体
// 没有包体时，传nil
- (NSData *)constructPacketData:(NSString *)pktHeader pktContent:(NSString *)pktContent {
    NSData *headerData = [pktHeader dataUsingEncoding:NSUTF8StringEncoding];
    NSData *contentData = [pktContent dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableData *data = [NSMutableData data];
    NSInteger infoLen = 4 + headerData.length + contentData.length;
//    [data appendData:[self dataWithInteger:infoLen]];
//    [data appendData:[self dataWithInteger:headerData.length]];
    [data appendData:headerData];
    if (contentData) {
        [data appendData:contentData];
    }
    return data;
}

#pragma mark -- socket 代理方法
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
    NSLog(@"链接成功: %@:%d",host,port);
    //第一次链接成功后,主动向服务器初始化一次
    [self sendInitData];
    //读取服务器传回来数据
    [self.socket readDataWithTimeout:-1 tag:123456];
}
//已经接受服务器返回来的数据
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
//    NSLog(@"接收成功：tag= %ld:%ld 长度的数据:%@",tag,data.length-1,[[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding]);
    //1.第一次接受数据
    if(self.dataArray == nil){
        self.dataArray =[NSMutableData data];
        //获取总的数据包大小
        NSData *totalSizeData = [data subdataWithRange:NSMakeRange(0, 4)];
        unsigned int totalSize = 0;
        //读取前四个字节
        [totalSizeData getBytes:&totalSize length:4];
        NSLog(@"接受总数据的大小 %u",totalSize);
        self.totalSize = totalSize;
        
        //获取指令类型
        NSData *commandIdData = [data subdataWithRange:NSMakeRange(4, 4)];
        unsigned int commandId = 0;
        [commandIdData getBytes:&commandId length:4];
        self.currentCommandID = commandId;
        switch (commandId) {
            case Image_Command:
                NSLog(@"此次上传是图片数据");
                break;
            case Text_Command:
                NSLog(@"此次上传是文本数据");
                break;

            default:
                self.currentCommandID =UNOWKEN_Command;
                NSLog(@"unnowken");
                break;
        }
        
    }
    //2。拼接二进制度
    [self.dataArray appendData:data];
    
    //3。图片数据已经接受完成
    //判断当前是否图片数据的最后一段
    NSLog(@"此次接受的额数据包大小,tag= %ld,%ld--%ld--%u",tag,data.length,self.dataArray.length, self.totalSize);
    if(self.dataArray.length == self.totalSize&&self.totalSize>0){
        // NSString *end = @"\t";
        NSData *endData =[self.dataArray subdataWithRange:NSMakeRange(self.dataArray.length-4,4)];
        //获取指令类型
        unsigned int splitLineCommandId = 0;
        [endData getBytes:&splitLineCommandId length:4];
        //分割符使用不太好
        if(splitLineCommandId == Split_Line_Command){
            NSLog(@"数据已经接受完成");
            //发送内容数据
            NSData *data =[NSData dataWithData:[self.dataArray subdataWithRange:NSMakeRange(8, self.dataArray.length-(8+4))]];
            self.dataArray = nil;
            self.totalSize = 0;
            NSLog(@"数据长度:,%ld",data.length);
            if(self.currentCommandID == Image_Command){
                dispatch_async(dispatch_get_global_queue(0,0),^{
                    UIImage *image = [UIImage imageWithData:data];
                    //存入相册
                    UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), (__bridge  void*)self);
                    dispatch_async(dispatch_get_main_queue(), ^{
                        NSLog(@"数据长度:,%ld",data.length);
                        self.imageView.image =image;
                    });
                });
            }else if(self.currentCommandID == Text_Command){
                NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
                //还原
            }
            self.currentCommandID =UNOWKEN_Command;
        }else{
            NSLog(@"数据完整性异常");
            self.dataArray = nil;
            self.totalSize = 0;
        }
    }
    [sock readDataWithTimeout:-1 tag:123456];
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
    NSLog(@"image= %@ error =%@ contextInfo =%@",image,error,contextInfo);
}
//信息发送成功 代理函数、向服务器 发送信息
-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
    NSLog(@"发送数据成功 tag=:%ld",tag);
    [sock readDataWithTimeout:-1 tag:123456];
}
-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
    NSLog(@"断开 socket链接 原因:%@",err);
    //进行重连
//    [self reConnectSocket];
    //响应客户端
    self.totalSize = 0;
    self.dataArray = nil;
    self.currentCommandID =UNOWKEN_Command;
    [self.dataArray replaceBytesInRange:NSMakeRange(0, 4) withBytes:NULL length:0];
}

@end
